using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;

public class ZipItem {
  public string Name { get; set; }          // 文件名（不包含路径）
  public string FullPath { get; set; }      // 文件在ZIP中的完整路径
  public long Size { get; set; }            // 文件大小（字节）
  public string TextContent { get; set; }   // 文件文本内容
  public byte[] Bytes { get; set; }         // 文件原始字节数据

  public override string ToString() {
    return $"{FullPath} ({Size} bytes)";
  }
}

public class ZipManager : IDisposable {  /// <summary>
  /// 统一使用UTF-8编码处理ZIP文件
  /// </summary>
  private static readonly Encoding ZipEncoding = Encoding.UTF8;
  private readonly ZipArchive _archive;
  private readonly Dictionary<string, ZipItem> _fileIndex = new Dictionary<string, ZipItem>(StringComparer.OrdinalIgnoreCase);

  /// <summary>
  /// 通过字节数组初始化ZipManager
  /// </summary>
  /// <param name="allBytes">ZIP文件的字节数组</param>
  /// <param name="encoding">指定编码，默认为GBK（解决中文乱码问题）</param>
  public ZipManager(byte[] allBytes, Encoding encoding = null) {
    var memoryStream = new MemoryStream(allBytes);
    _archive = new ZipArchive(memoryStream, ZipArchiveMode.Read, leaveOpen: false, ZipEncoding);
    BuildFileIndex();
  }

  /// <summary>
  /// 通过文件名初始化ZipManager
  /// </summary>
  /// <param name="filename">ZIP文件路径</param>
  /// <param name="encoding">指定编码，默认为GBK（解决中文乱码问题）</param>
  public ZipManager(string filename, Encoding encoding = null) {
    var fileStream = File.OpenRead(filename);
    _archive = new ZipArchive(fileStream, ZipArchiveMode.Read, leaveOpen: false, ZipEncoding);
    BuildFileIndex();
  }

  /// <summary>
  /// 构建文件索引
  /// </summary>
  private void BuildFileIndex() {
    foreach (var entry in _archive.Entries) {
      if (string.IsNullOrEmpty(entry.Name)) continue; // 跳过目录

      var fullPath = AdjustPath(entry.FullName);

      var zipItem = new ZipItem {
        Name = entry.Name,
        FullPath = entry.FullName,
        Size = entry.Length
      };

      // 添加到索引，使用不区分大小写的比较
      _fileIndex[fullPath] = zipItem;
    }
  }

  /// <summary>
  /// 获取ZIP中所有文件项
  /// </summary>
  public IEnumerable<ZipItem> GetAllItems() {
    return _fileIndex.Values;
  }

  private string AdjustPath(string path) {
    return path.ToLower().Replace("\\", "/");
  }

  /// <summary>
  /// 通过路径获取文件项（不区分大小写）
  /// </summary>
  /// <param name="path">文件在ZIP中的路径</param>
  /// <returns>ZipItem对象，如果不存在则返回null</returns>
  public ZipItem GetItem(string path) {
    var fixed_path = AdjustPath(path);
    _fileIndex.TryGetValue(fixed_path, out var item);
    if (item == null){
      Debuger.LogError($"Unable find zip path:{fixed_path}");
    }
    return item;
  }

  /// <summary>
  /// 通过路径获取文件项的项目
  /// </summary>
  /// <param name="path">文件在ZIP中的路径</param>
  /// <returns>ZipItem对象，如果不存在则返回null</returns>
  public string GetString(string path) {
    var item = GetItem(path);
    return item?.TextContent;
  }

  /// <summary>
  /// 读取所有文件内容并存储在ZipItem中
  /// </summary>
  public void ReadAllFiles() {
    foreach (var item in _fileIndex.Values) {
      ReadFileContent(item);
    }
  }

  /// <summary>
  /// 读取单个文件内容
  /// </summary>
  /// <param name="item">要读取的ZipItem</param>
  private void ReadFileContent(ZipItem item) {
    try {
      var entry = _archive.GetEntry(item.FullPath);
      if (entry != null) {
        using (var stream = entry.Open())
        using (var memoryStream = new MemoryStream()) {
          stream.CopyTo(memoryStream);
          item.Bytes = memoryStream.ToArray();

          // 尝试将内容解码为文本
          try {
            item.TextContent = Encoding.UTF8.GetString(item.Bytes);
          } catch {
            item.TextContent = "[Binary content]";
          }
        }
      }else{
        Debuger.LogError($"Unable find {item.FullPath} in file.");
        item.TextContent = "";
      }
    } catch (Exception ex) {
      item.TextContent = $"[Error reading file: {ex.Message}]";
    }
  }




  public static IEnumerable<string> ReadZipContents(string zipPath) {
    if (!File.Exists(zipPath)) {
      throw new FileNotFoundException("ZIP文件不存在", zipPath);
    }

    var contents = new List<string>();
    using (var fileStream = File.OpenRead(zipPath))
    using (var archive = new ZipArchive(fileStream, ZipArchiveMode.Read, false, ZipEncoding)) {
      foreach (var entry in archive.Entries) {
        if (string.IsNullOrEmpty(entry.Name)) continue;

        using (var stream = entry.Open())
        using (var reader = new StreamReader(stream, ZipEncoding)) {
          contents.Add($"{entry.FullName}: {reader.ReadToEnd()}");
        }
      }
    }
    return contents;
  }

  /// <summary>
  /// 释放资源
  /// </summary>
  public void Dispose() {
    _archive?.Dispose();
  }
}